#include"ngram_lm.h"
#include"../../util.h"

NgramLanguageModel::NgramLanguageModel(int gram)
{
	this->gram = gram;
}

NgramLanguageModel::NgramLanguageModel(int gram, string info)
{
	this->gram = gram;
	load(info);
}

double NgramLanguageModel::prob(string query, map<string, int> &lm)
{
	vector<string> v = util::tokenize(query, " ");
	double score = 1;
	for(int i = 0; i < v.size(); ++ i){
		string base;
		string cur;
		for(int j = i; j > i - gram; -- j)
		{
			if(j < 0)break;
			cur += v[j];
			cur += " ";
		}
		for(int j = i - 1; j > i - gram; -- j)
		{
			if(j < 0)break;
			base += v[j];
			base += " ";
		}
		base = util::sort_v(base);
		cur = util::sort_v(cur);
		double base_score = (base.length() > 0)? (*lm.find(base)).second:1;
		double cur_score = (double)(*lm.find(cur)).second/base_score;
		score *= cur_score;
	}
	return score;
}

double NgramLanguageModel::prob(string query)
{
		vector<string> v = util::tokenize(query, " ");
	double score = 1;
	for(int i = 0; i < v.size(); ++ i){
		string base;
		string cur;
		for(int j = i; j > i - gram; -- j)
		{
			if(j < 0)break;
			cur += v[j];
			cur += " ";
		}
		for(int j = i - 1; j > i - gram; -- j)
		{
			if(j < 0)break;
			base += v[j];
			base += " ";
		}
		base = util::sort_v(base);
		cur = util::sort_v(cur);
		double base_score = (base.length() > 0)? (*model.find(base)).second:1;
		double cur_score = (double)(*model.find(cur)).second/base_score;
		score *= cur_score;
	}
	return score;
}

void NgramLanguageModel::load(string line)
{
	vector<string> pattern_list = util::tokenize_h(line, " | ");
	for(int i = 0; i < pattern_list.size(); ++ i)
	{
		string pattern = pattern_list[i];
		int del = pattern.find("\t");
		string base = pattern.substr(0, del);
		string freq_c = pattern.substr(del + 1, pattern.length() - del - 1);
		int freq = atoi(freq_c.c_str());
		model.insert(pair<string, int>(base, freq));
	}
}
